home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmbase-grok-1.2 / sectwin.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  9KB  |  287 lines

  1. /*
  2.  * Create and destroy the add-section popup.
  3.  *
  4.  *    destroy_newsect_popup()
  5.  *    create_newsect_popup()
  6.  */
  7.  
  8. #include "config.h"
  9. #include <X11/Xos.h>
  10. #include <stdlib.h>
  11. #include <sys/stat.h>
  12. #include <errno.h>
  13. #include <Xm/Xm.h>
  14. #include <Xm/DialogS.h>
  15. #include <Xm/Form.h>
  16. #include <Xm/LabelP.h>
  17. #include <Xm/LabelG.h>
  18. #include <Xm/PushBP.h>
  19. #include <Xm/PushBG.h>
  20. #include <Xm/Text.h>
  21. #include <Xm/ToggleB.h>
  22. #include <Xm/Separator.h>
  23. #include <Xm/Protocols.h>
  24. #include "grok.h"
  25. #include "form.h"
  26. #include "proto.h"
  27.  
  28. extern Display    *display;    /* everybody uses the same server */
  29. extern Pixel    color[NCOLS];    /* colors: COL_* */
  30. extern CARD     *curr_card;    /* card being displayed in main win */
  31. extern int    errno;
  32. extern Widget    toplevel;    /* top-level shell for error popup */
  33.  
  34. static BOOL    have_shell;    /* message popup exists if TRUE */
  35. static Widget    shell;        /* popup menu shell */
  36. static Widget    w_name;        /* name entry widget */
  37.  
  38.  
  39. /*
  40.  * destroy a popup. Remove it from the screen, and destroy its widgets.
  41.  * It's too much trouble to keep them for next time.
  42.  */
  43.  
  44. void destroy_newsect_popup(void)
  45. {
  46.     if (have_shell) {
  47.         XtPopdown(shell);
  48.         XtDestroyWidget(shell);
  49.         have_shell = FALSE;
  50.     }
  51. }
  52.  
  53.  
  54. /*
  55.  * create a new-section popup as a separate application shell.
  56.  */
  57.  
  58. static void add_callback(Widget, int, XmToggleButtonCallbackStruct *);
  59. static void can_callback(Widget, int, XmToggleButtonCallbackStruct *);
  60.  
  61. void create_newsect_popup(void)
  62. {
  63.     Widget            form, w, wt;
  64.     Arg            args[20];
  65.     int            n;
  66.     Atom            closewindow;
  67.  
  68.     destroy_newsect_popup();
  69.     if (!curr_card || !curr_card->dbase)
  70.         return;
  71.  
  72.     n = 0;
  73.     XtSetArg(args[n], XmNdeleteResponse,    XmDO_NOTHING);        n++;
  74.     XtSetArg(args[n], XmNiconic,        False);            n++;
  75.     shell = XtAppCreateShell("New Section", "Grok",
  76.             applicationShellWidgetClass, display, args, n);
  77.     set_icon(shell, 1);
  78.     form = XtCreateManagedWidget("addsectform", xmFormWidgetClass,
  79.             shell, NULL, 0);
  80.     XtAddCallback(form, XmNhelpCallback,
  81.             (XtCallbackProc)help_callback, (XtPointer)"addsect");
  82.  
  83.                             /*-- section name --*/
  84.     n = 0;
  85.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_FORM);        n++;
  86.     XtSetArg(args[n], XmNtopOffset,        12);            n++;
  87.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  88.     XtSetArg(args[n], XmNleftOffset,    16);            n++;
  89.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  90.     XtSetArg(args[n], XmNrightOffset,    16);            n++;
  91.     w = XtCreateManagedWidget("Enter a short name for the new section:",
  92.                 xmLabelWidgetClass, form, args, n);
  93.  
  94.     n = 0;
  95.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  96.     XtSetArg(args[n], XmNtopWidget,        w);            n++;
  97.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  98.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  99.     XtSetArg(args[n], XmNleftOffset,    16);            n++;
  100.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  101.     XtSetArg(args[n], XmNrightOffset,    16);            n++;
  102.     XtSetArg(args[n], XmNbackground,    color[COL_TEXTBACK]);    n++;
  103.     w_name = XtCreateManagedWidget("sectname",
  104.                 xmTextWidgetClass, form, args, n);
  105.     XtAddCallback(w_name, XmNactivateCallback,
  106.                 (XtCallbackProc)add_callback, NULL);
  107.  
  108.     n = 0;
  109.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  110.     XtSetArg(args[n], XmNtopWidget,        w_name);        n++;
  111.     XtSetArg(args[n], XmNtopOffset,        16);            n++;
  112.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  113.     XtSetArg(args[n], XmNleftOffset,    16);            n++;
  114.     wt = XtCreateManagedWidget(
  115.         !curr_card->dbase->havesects && curr_card->dbase->nrows
  116.             ? "All cards will be put into the new section."
  117.             : "The new section will be empty.",
  118.         xmLabelWidgetClass, form, args, n);
  119.  
  120.                             /*-- buttons --*/
  121.     n = 0;
  122.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  123.     XtSetArg(args[n], XmNtopWidget,        wt);            n++;
  124.     XtSetArg(args[n], XmNtopOffset,        16);            n++;
  125.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_FORM);        n++;
  126.     XtSetArg(args[n], XmNbottomOffset,    8);            n++;
  127.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  128.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  129.     XtSetArg(args[n], XmNwidth,        80);            n++;
  130.     w = XtCreateManagedWidget("Add",
  131.             xmPushButtonWidgetClass, form, args, n);
  132.     XtAddCallback(w, XmNactivateCallback,
  133.             (XtCallbackProc)add_callback, (XtPointer)"addsect");
  134.     XtAddCallback(w, XmNhelpCallback,
  135.             (XtCallbackProc)help_callback, (XtPointer)"addsect");
  136.  
  137.     n = 0;
  138.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  139.     XtSetArg(args[n], XmNtopWidget,        wt);            n++;
  140.     XtSetArg(args[n], XmNtopOffset,        16);            n++;
  141.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_FORM);        n++;
  142.     XtSetArg(args[n], XmNbottomOffset,    8);            n++;
  143.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_WIDGET);    n++;
  144.     XtSetArg(args[n], XmNrightWidget,    w);            n++;
  145.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  146.     XtSetArg(args[n], XmNwidth,        80);            n++;
  147.     w = XtCreateManagedWidget("Cancel",
  148.             xmPushButtonWidgetClass, form, args, n);
  149.     XtAddCallback(w, XmNactivateCallback,
  150.             (XtCallbackProc)can_callback, (XtPointer)0);
  151.     XtAddCallback(w, XmNhelpCallback,
  152.             (XtCallbackProc)help_callback, (XtPointer)"addsect");
  153.  
  154.     n = 0;
  155.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  156.     XtSetArg(args[n], XmNtopWidget,        wt);            n++;
  157.     XtSetArg(args[n], XmNtopOffset,        16);            n++;
  158.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_FORM);        n++;
  159.     XtSetArg(args[n], XmNbottomOffset,    8);            n++;
  160.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_WIDGET);    n++;
  161.     XtSetArg(args[n], XmNrightWidget,    w);            n++;
  162.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  163.     XtSetArg(args[n], XmNwidth,        80);            n++;
  164.     w = XtCreateManagedWidget("Help",
  165.             xmPushButtonWidgetClass, form, args, n);
  166.     XtAddCallback(w, XmNactivateCallback,
  167.             (XtCallbackProc)help_callback, (XtPointer)"addsect");
  168.     XtAddCallback(w, XmNhelpCallback,
  169.             (XtCallbackProc)help_callback, (XtPointer)"addsect");
  170.  
  171.     XtPopup(shell, XtGrabNone);
  172.     closewindow = XmInternAtom(display, "WM_DELETE_WINDOW", False);
  173.     XmAddWMProtocolCallback(shell, closewindow,
  174.             (XtCallbackProc)can_callback, (XtPointer)0);
  175.     have_shell = TRUE;
  176. }
  177.  
  178.  
  179. /*-------------------------------------------------- callbacks --------------*/
  180. /*
  181.  * All of these routines are direct X callbacks.
  182.  */
  183.  
  184. /*ARGSUSED*/
  185. static void add_callback(
  186.     Widget                widget,
  187.     int                item,
  188.     XmToggleButtonCallbackStruct    *data)
  189. {
  190.     register DBASE            *dbase;
  191.     register SECTION        *sect;
  192.     register char            *name, *p;
  193.     register int            i, s, fd;
  194.     char                *path, old[1024], new[1024];
  195.     BOOL                nofile = FALSE;
  196.  
  197.     if (!curr_card || !(dbase = curr_card->dbase)) {
  198.         destroy_newsect_popup();
  199.         return;
  200.     }
  201.     name = read_text_button(w_name, 0);
  202.     while (*name == ' ' || *name == '\t')
  203.         name++;
  204.     for (p=name; *p; p++)
  205.         if (strchr(" \t\n/!$&*()[]{};'\"`<>?\\|", *p))
  206.             *p = '_';
  207.     if ((p = strrchr(name, '.')) && !strcmp(p, ".db"))
  208.         *p = 0;
  209.     for (s=0; s < dbase->nsects; s++)
  210.         if (!strcmp(name, section_name(dbase, s))) {
  211.             create_error_popup(shell, 0,
  212.                 "A section with this name already exists.");
  213.             return;
  214.         }
  215.     path = resolve_tilde(curr_card->form->dbase, "db");
  216.     sprintf(old, "%s.old", path);
  217.     sprintf(new, "%s/%s.db", path, name);
  218.     if (!dbase->havesects) {
  219.         (void)unlink(old);
  220.         if (link(path, old))
  221.             if (!(nofile = errno == ENOENT)) {
  222.                 create_error_popup(shell, errno,
  223.                     "Could not link %s\nto %s", path, old);
  224.                 return;
  225.             }
  226.         if (unlink(path) && !nofile) {
  227.             create_error_popup(shell, errno,
  228.                 "Could not unlink\n%s", path);
  229.             (void)link(old, path);
  230.             return;
  231.         }
  232.         if (mkdir(path, 0700)) {
  233.             create_error_popup(shell, errno,
  234.                 "Could not create directory\n%s", path);
  235.             return;
  236.         }
  237.         if (!nofile && link(old, new)) {
  238.             create_error_popup(shell, errno,
  239.                    "Could not link %s\nto %s,\nleaving file in %s",
  240.                             old, new, old);
  241.             return;
  242.         }
  243.         (void)unlink(old);
  244.     }
  245.     if (dbase->havesects || nofile) {
  246.         if ((fd = creat(new, 0600)) < 0) {
  247.             create_error_popup(shell, errno,
  248.                 "Could not create empty file\n%s", new);
  249.             return;
  250.         }
  251.         close(fd);
  252.     }
  253.     if (dbase->havesects) {
  254.         i = (dbase->nsects+1) * sizeof(SECTION);
  255.         if (!(sect = dbase->sect ? realloc(dbase->sect,i):malloc(i))) {
  256.             create_error_popup(toplevel, errno,
  257.                         "No memory for new section");
  258.             return;
  259.         }
  260.         dbase->sect = sect;
  261.         mybzero(sect = &dbase->sect[dbase->nsects], sizeof(SECTION));
  262.         dbase->currsect = dbase->nsects++;
  263.     } else {
  264.         sect = dbase->sect;
  265.         if (sect->path)
  266.             free(sect->path);
  267.     }
  268.     sect->mtime    = time(0);
  269.     sect->path    = mystrdup(new);
  270.     sect->modified    = TRUE;
  271.     dbase->modified    = TRUE;
  272.     dbase->havesects= TRUE;
  273.  
  274.     remake_section_pulldown();
  275.     print_info_line();
  276.     destroy_newsect_popup();
  277. }
  278.  
  279. /*ARGSUSED*/
  280. static void can_callback(
  281.     Widget                widget,
  282.     int                item,
  283.     XmToggleButtonCallbackStruct    *data)
  284. {
  285.     destroy_newsect_popup();
  286. }
  287.